home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_ncurses.idb / usr / freeware / include / ncurses / cursesm.h.z / cursesm.h
Encoding:
C/C++ Source or Header  |  1999-07-16  |  17.3 KB  |  593 lines

  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3.  * Copyright (c) 1998 Free Software Foundation, Inc.                        *
  4.  *                                                                          *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  6.  * copy of this software and associated documentation files (the            *
  7.  * "Software"), to deal in the Software without restriction, including      *
  8.  * without limitation the rights to use, copy, modify, merge, publish,      *
  9.  * distribute, distribute with modifications, sublicense, and/or sell       *
  10.  * copies of the Software, and to permit persons to whom the Software is    *
  11.  * furnished to do so, subject to the following conditions:                 *
  12.  *                                                                          *
  13.  * The above copyright notice and this permission notice shall be included  *
  14.  * in all copies or substantial portions of the Software.                   *
  15.  *                                                                          *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  19.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  22.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  23.  *                                                                          *
  24.  * Except as contained in this notice, the name(s) of the above copyright   *
  25.  * holders shall not be used in advertising or otherwise to promote the     *
  26.  * sale, use or other dealings in this Software without prior written       *
  27.  * authorization.                                                           *
  28.  ****************************************************************************/
  29.  
  30. /****************************************************************************
  31.  *   Author: Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> 1997             *
  32.  ****************************************************************************/
  33.  
  34. // $Id: cursesm.h,v 1.9 1998/02/11 12:13:41 tom Exp $
  35.  
  36. #ifndef _CURSESM_H
  37. #define _CURSESM_H
  38.  
  39. #include <cursesp.h>
  40.  
  41. extern "C" {
  42. #  include <menu.h>
  43. }
  44. //
  45. // -------------------------------------------------------------------------
  46. // This wraps the ITEM type of <menu.h>
  47. // -------------------------------------------------------------------------
  48. //
  49. class NCursesMenuItem {
  50.   friend class NCursesMenu;
  51.   
  52. protected:
  53.   ITEM *item;
  54.  
  55.   inline void OnError (int err) const THROWS(NCursesMenuException) {
  56.     if (err != E_OK)
  57.       THROW(new NCursesMenuException (err));
  58.   }
  59.  
  60. public:
  61.   NCursesMenuItem (const char* p_name     = NULL,
  62.            const char* p_descript = NULL ) { 
  63.     item = p_name ? ::new_item (p_name, p_descript) : (ITEM*)0; 
  64.     if (p_name && !item)
  65.       OnError (E_SYSTEM_ERROR);
  66.   }
  67.   // Create an item. If you pass both parameters as NULL, a delimiting
  68.   // item is constructed which can be used to terminate a list of
  69.   // NCursesMenu objects.
  70.   
  71.   virtual ~NCursesMenuItem ();
  72.   // Release the items memory
  73.  
  74.   inline const char* name () const {
  75.     return ::item_name (item);
  76.   }
  77.   // Name of the item
  78.  
  79.   inline const char* description () const {
  80.     return ::item_description (item);
  81.   }
  82.   // Description of the item
  83.   
  84.   inline int index (void) const {
  85.     return ::item_index (item);
  86.   }
  87.   // Index of the item in an item array (or -1)
  88.  
  89.   inline void options_on (Item_Options options) {
  90.     OnError (::item_opts_on (item, options));
  91.   }
  92.   // Switch on the items options
  93.  
  94.   inline void options_off (Item_Options options) {
  95.     OnError (::item_opts_off (item, options));
  96.   }
  97.   // Switch off the item's option
  98.  
  99.   inline Item_Options options () const {
  100.     return ::item_opts (item);
  101.   }
  102.   // Retrieve the items options
  103.  
  104.   inline void set_options (Item_Options options) {
  105.     OnError (::set_item_opts (item, options));
  106.   }
  107.   // Set the items options
  108.  
  109.   inline void set_value (bool f) {
  110.     OnError (::set_item_value (item,f));
  111.   }
  112.   // Set/Reset the items selection state
  113.  
  114.   inline bool value () const {
  115.     return ::item_value (item);
  116.   }
  117.   // Retrieve the items selection state
  118.   
  119.   inline bool visible () const {
  120.     return ::item_visible (item);
  121.   }
  122.   // Retrieve visibility of the item
  123.  
  124.   virtual bool action();
  125.   // Perform an action associated with this item; you may use this in an
  126.   // user supplied driver for a menu; you may derive from this class and
  127.   // overload action() to supply items with different actions.
  128.   // If an action returns true, the menu will be exited. The default action
  129.   // is to do nothing.
  130. };
  131.  
  132. // Prototype for an items callback function.
  133. typedef bool ITEMCALLBACK(NCursesMenuItem&);
  134.  
  135. // If you don't like to create a child class for individual items to
  136. // overload action(), you may use this class and provide a callback
  137. // function pointer for items.
  138. class NCursesMenuCallbackItem : public NCursesMenuItem {
  139. private:
  140.   const ITEMCALLBACK* p_fct;
  141.  
  142. public:
  143.   NCursesMenuCallbackItem(const ITEMCALLBACK* fct = NULL,
  144.               const char* p_name      = NULL,
  145.               const char* p_descript  = NULL )
  146.     : NCursesMenuItem (p_name, p_descript),
  147.       p_fct (fct) {
  148.   }
  149.   
  150.   virtual ~NCursesMenuCallbackItem();
  151.  
  152.   bool action();
  153. };
  154. //
  155. // -------------------------------------------------------------------------
  156. // This wraps the MENU type of <menu.h>
  157. // -------------------------------------------------------------------------
  158. //
  159. class NCursesMenu : public NCursesPanel {
  160. protected:
  161.   MENU *menu;
  162.  
  163. private:
  164.   NCursesWindow* sub;   // the subwindow object
  165.   bool b_sub_owner;     // is this our own subwindow?
  166.   bool b_framed;        // has the menu a border?
  167.   bool b_autoDelete;    // Delete items when deleting menu?
  168.  
  169.   NCursesMenuItem** my_items; // The array of items for this menu
  170.  
  171.   // This structure is used for the menu's user data field to link the
  172.   // MENU* to the C++ object and to provide extra space for a user pointer.
  173.   typedef struct {
  174.     void*              m_user;      // the pointer for the user's data
  175.     const NCursesMenu* m_back;      // backward pointer to C++ object
  176.     const MENU*        m_owner;
  177.   } UserHook;
  178.  
  179.   // Get the backward pointer to the C++ object from a MENU
  180.   static inline NCursesMenu* getHook(const MENU *m) {
  181.     UserHook* hook = (UserHook*)::menu_userptr(m);
  182.     assert(hook && hook->m_owner==m);
  183.     return (NCursesMenu*)(hook->m_back);
  184.   }
  185.  
  186.   // This are the built-in hook functions in this C++ binding. In C++ we use
  187.   // virtual member functions (see below On_..._Init and On_..._Termination)
  188.   // to provide this functionality in an object oriented manner.
  189.   static void mnu_init(MENU *);
  190.   static void mnu_term(MENU *);
  191.   static void itm_init(MENU *);
  192.   static void itm_term(MENU *);
  193.   
  194.   // Calculate ITEM* array for the menu
  195.   ITEM** mapItems(NCursesMenuItem* nitems[]);
  196.   
  197. protected:
  198.   // internal routines 
  199.   inline void set_user(void *user) {
  200.     UserHook* uptr = (UserHook*)::menu_userptr (menu);
  201.     assert (uptr && uptr->m_back==this && uptr->m_owner==menu);
  202.     uptr->m_user = user;
  203.   }
  204.  
  205.   inline void *get_user() {
  206.     UserHook* uptr = (UserHook*)::menu_userptr (menu);
  207.     assert (uptr && uptr->m_back==this && uptr->m_owner==menu);
  208.     return uptr->m_user;
  209.   }  
  210.   
  211.   void InitMenu (NCursesMenuItem* menu[],
  212.          bool with_frame,
  213.          bool autoDeleteItems);
  214.  
  215.   inline void OnError (int err) const THROWS(NCursesMenuException) {
  216.     if (err != E_OK)
  217.       THROW(new NCursesMenuException (this, err));
  218.   }
  219.   
  220.   // this wraps the menu_driver call.
  221.   virtual int driver (int c) ;
  222.   
  223.   // 'Internal' constructor to create a menu without association to
  224.   // an array of items.
  225.   NCursesMenu( int  lines, 
  226.            int  cols, 
  227.            int  begin_y = 0, 
  228.            int  begin_x = 0) 
  229.     : NCursesPanel(lines,cols,begin_y,begin_x), 
  230.       menu ((MENU*)0) {
  231.   }
  232.  
  233. public:
  234.   // Make a full window size menu
  235.   NCursesMenu (NCursesMenuItem* Items[],
  236.            bool with_frame=FALSE,        // Reserve space for a frame?
  237.            bool autoDelete_Items=FALSE)  // Autocleanup of Items?
  238.     : NCursesPanel() {
  239.       InitMenu(Items, with_frame, autoDelete_Items);
  240.   }
  241.  
  242.   // Make a menu with a window of this size.
  243.   NCursesMenu (NCursesMenuItem* Items[], 
  244.            int  lines, 
  245.            int  cols, 
  246.            int  begin_y = 0, 
  247.            int  begin_x = 0,
  248.            bool with_frame=FALSE,        // Reserve space for a frame?
  249.            bool autoDelete_Items=FALSE)  // Autocleanup of Items?
  250.     : NCursesPanel(lines, cols, begin_y, begin_x) {
  251.       InitMenu(Items, with_frame, autoDelete_Items);
  252.   }
  253.  
  254.   virtual ~NCursesMenu ();
  255.  
  256.   // Retrieve the menus subwindow
  257.   inline NCursesWindow& subWindow() const {
  258.     assert(sub!=NULL);
  259.     return *sub;
  260.   }
  261.  
  262.   // Set the menus subwindow
  263.   void setSubWindow(NCursesWindow& sub);
  264.  
  265.   // Set these items for the menu
  266.   inline void setItems(NCursesMenuItem* Items[]) {
  267.     OnError(::set_menu_items(menu,mapItems(Items)));    
  268.   }
  269.  
  270.   // Remove the menu from the screen
  271.   inline void unpost (void) { 
  272.     OnError (::unpost_menu (menu)); 
  273.   }
  274.   
  275.   // Post the menu to the screen if flag is true, unpost it otherwise
  276.   inline void post(bool flag = TRUE) {
  277.     flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu)); 
  278.   }
  279.  
  280.   // Get the numer of rows and columns for this menu
  281.   inline void scale (int& mrows, int& mcols) const  {
  282.     OnError (::scale_menu (menu, &mrows, &mcols));
  283.   }
  284.  
  285.   // Set the format of this menu
  286.   inline void set_format(int mrows, int mcols) {
  287.     OnError (::set_menu_format(menu, mrows, mcols));
  288.   }
  289.   
  290.   // Get the format of this menu
  291.   inline void menu_format(int& rows,int& cols) { 
  292.     ::menu_format(menu,&rows,&cols); 
  293.   }
  294.   
  295.   // Items of the menu
  296.   inline NCursesMenuItem* items() const {
  297.     return *my_items; 
  298.   }
  299.  
  300.   // Get the number of items in this menu
  301.   inline int count() const {
  302.     return ::item_count(menu); 
  303.   }
  304.  
  305.   // Get the current item (i.e. the one the cursor is located)
  306.   inline NCursesMenuItem* current_item() const {
  307.     return my_items[::item_index(::current_item(menu))];
  308.   }
  309.   
  310.   // Get the marker string
  311.   inline const char* mark() const {
  312.     return ::menu_mark(menu);
  313.   }
  314.  
  315.   // Set the marker string
  316.   inline void set_mark(const char *mark) {
  317.     OnError (::set_menu_mark (menu, mark));
  318.   }
  319.  
  320.   // Get the name of the request code c
  321.   inline static const char* request_name(int c) {
  322.     return ::menu_request_name(c);
  323.   }
  324.  
  325.   // Get the current pattern
  326.   inline char* pattern() const {
  327.     return ::menu_pattern(menu);
  328.   }
  329.  
  330.   // true if there is a pattern match, false otherwise.
  331.   bool set_pattern (const char *pat);
  332.  
  333.   // set the default attributes for the menu
  334.   // i.e. set fore, back and grey attribute
  335.   virtual void setDefaultAttributes();
  336.  
  337.   // Get the menus background attributes
  338.   inline chtype back() const {
  339.     return ::menu_back(menu);
  340.   }
  341.  
  342.   // Get the menus foreground attributes
  343.   inline chtype fore() const {
  344.     return ::menu_fore(menu);
  345.   }
  346.  
  347.   // Get the menus grey attributes (used for unselectable items)
  348.   inline chtype grey() const {
  349.     return ::menu_grey(menu);
  350.   }
  351.  
  352.   // Set the menus background attributes
  353.   inline chtype set_background(chtype a) {
  354.     return ::set_menu_back(menu,a);
  355.   }
  356.  
  357.   // Set the menus foreground attributes
  358.   inline chtype set_foreground(chtype a) {
  359.     return ::set_menu_fore(menu,a);
  360.   }
  361.  
  362.   // Set the menus grey attributes (used for unselectable items)
  363.   inline chtype set_grey(chtype a) {
  364.     return ::set_menu_grey(menu,a);
  365.   }
  366.   
  367.   inline void options_on (Menu_Options opts) {
  368.     OnError (::menu_opts_on (menu,opts));
  369.   }
  370.  
  371.   inline void options_off(Menu_Options opts) {
  372.     OnError (::menu_opts_off(menu,opts));
  373.   }
  374.  
  375.   inline Menu_Options options() const {
  376.     return ::menu_opts(menu);
  377.   }
  378.   
  379.   inline void set_options (Menu_Options opts) {
  380.     OnError (::set_menu_opts (menu,opts));
  381.   }
  382.  
  383.   inline int pad() const {
  384.     return ::menu_pad(menu);
  385.   }
  386.  
  387.   inline void set_pad (int padch) {
  388.     OnError (::set_menu_pad (menu, padch));
  389.   }
  390.   
  391.   // Position the cursor to the current item
  392.   inline void position_cursor () const {
  393.     OnError (::pos_menu_cursor (menu));
  394.   }
  395.  
  396.   // Set the current item
  397.   inline void set_current(NCursesMenuItem& I) {
  398.     OnError (::set_current_item(menu, I.item));
  399.   }
  400.  
  401.   // Get the current top row of the menu
  402.   inline int top_row (void) const {
  403.     return ::top_row (menu);
  404.   }
  405.  
  406.   // Set the current top row of the menu
  407.   inline void set_top_row (int row) {
  408.     OnError (::set_top_row (menu, row));
  409.   }
  410.  
  411.   // spacing control
  412.   // Set the spacing for the menu
  413.   inline void setSpacing(int spc_description,
  414.              int spc_rows,
  415.              int spc_columns) {
  416.     OnError(::set_menu_spacing(menu,
  417.                    spc_description,
  418.                    spc_rows,
  419.                    spc_columns));
  420.   }
  421.   
  422.   // Get the spacing info for the menu
  423.   inline void Spacing(int& spc_description,
  424.               int& spc_rows,
  425.               int& spc_columns) const {
  426.     OnError(::menu_spacing(menu,
  427.                &spc_description,
  428.                &spc_rows,
  429.                &spc_columns));
  430.   }
  431.  
  432.   // Decorations
  433.   inline void frame(const char *title=NULL, const char* btitle=NULL) {
  434.     if (b_framed)
  435.       NCursesPanel::frame(title,btitle);
  436.     else
  437.       OnError(E_SYSTEM_ERROR);
  438.   }
  439.  
  440.   inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
  441.     if (b_framed)
  442.       NCursesPanel::boldframe(title,btitle);
  443.     else
  444.       OnError(E_SYSTEM_ERROR);
  445.   }
  446.   
  447.   inline void label(const char *topLabel, const char *bottomLabel) {
  448.     if (b_framed)
  449.       NCursesPanel::label(topLabel,bottomLabel);
  450.     else
  451.       OnError(E_SYSTEM_ERROR);
  452.   }
  453.  
  454.   // -----
  455.   // Hooks
  456.   // -----
  457.  
  458.   // Called after the menu gets repositioned in its window.
  459.   // This is especially true if the menu is posted.
  460.   virtual void On_Menu_Init();
  461.  
  462.   // Called before the menu gets repositioned in its window.
  463.   // This is especially true if the menu is unposted.
  464.   virtual void On_Menu_Termination();
  465.  
  466.   // Called after the item became the current item
  467.   virtual void On_Item_Init(NCursesMenuItem& item);
  468.  
  469.   // Called before this item is left as current item.
  470.   virtual void On_Item_Termination(NCursesMenuItem& item);
  471.   
  472.   // Provide a default key virtualization. Translate the keyboard
  473.   // code c into a menu request code.
  474.   // The default implementation provides a hopefully straightforward
  475.   // mapping for the most common keystrokes and menu requests.
  476.   virtual int virtualize(int c);
  477.  
  478.  
  479.   // Operators
  480.   inline NCursesMenuItem* operator[](int i) const {
  481.     if ( (i < 0) || (i >= ::item_count (menu)) )
  482.       OnError (E_BAD_ARGUMENT);
  483.     return (my_items[i]);
  484.   }
  485.  
  486.   // Perform the menu's operation
  487.   // Return the item where you left the selection mark for a single
  488.   // selection menu, or NULL for a multivalued menu.
  489.   virtual NCursesMenuItem* operator()(void);
  490.  
  491.   // --------------------
  492.   // Exception handlers
  493.   // Called by operator()
  494.   // --------------------
  495.  
  496.   // Called if the request is denied
  497.   virtual void On_Request_Denied(int c) const;
  498.   
  499.   // Called if the item is not selectable
  500.   virtual void On_Not_Selectable(int c) const;
  501.  
  502.   // Called if pattern doesn't match
  503.   virtual void On_No_Match(int c) const;
  504.  
  505.   // Called if the command is unknown
  506.   virtual void On_Unknown_Command(int c) const;
  507.  
  508. };
  509. //
  510. // -------------------------------------------------------------------------
  511. // This is the typical C++ typesafe way to allow to attach
  512. // user data to an item of a menu. Its assumed that the user
  513. // data belongs to some class T. Use T as template argument
  514. // to create a UserItem.
  515. // -------------------------------------------------------------------------
  516. //
  517. template<class T> class NCursesUserItem : public NCursesMenuItem
  518. {
  519. public:
  520.   NCursesUserItem (const char* p_name,
  521.            const char* p_descript = NULL,
  522.            const T* p_UserData    = (T*)0)
  523.     : NCursesMenuItem (p_name, p_descript) {
  524.       if (item)
  525.     OnError (::set_item_userptr (item, (void *)p_UserData));
  526.   };
  527.  
  528.   virtual ~NCursesUserItem() {};
  529.  
  530.   inline const T* UserData (void) const {
  531.     return (const T*)::item_userptr (item);
  532.   };
  533.  
  534.   inline virtual void setUserData(const T* p_UserData) {
  535.     if (item)
  536.       OnError (::set_item_userptr (item, (void *)p_UserData));
  537.   }
  538. };
  539. //
  540. // -------------------------------------------------------------------------
  541. // The same mechanism is used to attach user data to a menu
  542. // -------------------------------------------------------------------------
  543. //
  544. template<class T> class NCursesUserMenu : public NCursesMenu
  545. {
  546. protected:
  547.   NCursesUserMenu( int  lines, 
  548.            int  cols, 
  549.            int  begin_y = 0, 
  550.            int  begin_x = 0,
  551.            const T* p_UserData = (T*)0) 
  552.     : NCursesMenu(lines,cols,begin_y,begin_x) {
  553.       if (menu)
  554.     set_user ((void *)p_UserData);
  555.   }
  556.  
  557. public:
  558.   NCursesUserMenu (NCursesMenuItem Items[],
  559.            const T* p_UserData = (T*)0,
  560.            bool with_frame=FALSE,
  561.            bool autoDelete_Items=FALSE)
  562.     : NCursesMenu (Items, with_frame, autoDelete_Items) {
  563.       if (menu)
  564.     set_user ((void *)p_UserData);
  565.   };
  566.   
  567.   NCursesUserMenu (NCursesMenuItem Items[],
  568.            int lines, 
  569.            int cols, 
  570.            int begin_y = 0, 
  571.            int begin_x = 0,
  572.            const T* p_UserData = (T*)0,
  573.            bool with_frame=FALSE)
  574.     : NCursesMenu (Items, lines, cols, begin_y, begin_x, with_frame) {
  575.       if (menu)
  576.     set_user ((void *)p_UserData);
  577.   };  
  578.   
  579.   virtual ~NCursesUserMenu() {
  580.   };
  581.   
  582.   inline T* UserData (void) const {
  583.     return (T*)get_user ();
  584.   };
  585.  
  586.   inline virtual void setUserData (const T* p_UserData) {
  587.     if (menu)
  588.       set_user ((void *)p_UserData);
  589.   }
  590. };
  591.  
  592. #endif // _CURSESM_H
  593.